package net.vinote.smart.platform.tool.image;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

/**
 * 缩略图生成器
 * 
 * @author Seer
 *
 */
public class ThumbnailGeneral {
	/**
	 * 生成缩略图
	 * 
	 * @param pic
	 * @param width
	 * @param height
	 * @return
	 */
	public static byte[] generateThumbnail(byte[] pic, int width, int height) {
		try {
			BufferedImage cutImage = cropImage(pic, width * 1.0 / height);
			BufferedImage srcImage = thumbnail(cutImage, width, height);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ImageIO.write(srcImage, "png", out);
			return out.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 生成缩略图
	 * 
	 * @param source
	 *            原图
	 * @param targetW
	 *            缩略图宽度
	 * @param targetH
	 *            缩略图高度
	 * @return
	 */
	private static BufferedImage thumbnail(BufferedImage source, int targetW,
			int targetH) {
		// targetW，targetH分别表示目标长和宽
		int type = source.getType();
		BufferedImage target = null;
		double sx = (double) targetW / source.getWidth();
		double sy = (double) targetH / source.getHeight();
		// 这里想实现在targetW，targetH范围内实现等比缩放。如果不需要等比缩放
		// 则将下面的if else语句注释即可
		if (sx > sy) {
			sx = sy;
			targetW = (int) (sx * source.getWidth());
		} else {
			sy = sx;
			targetH = (int) (sy * source.getHeight());
		}
		if (type == BufferedImage.TYPE_CUSTOM) { // handmade
			ColorModel cm = source.getColorModel();
			WritableRaster raster = cm.createCompatibleWritableRaster(targetW,
					targetH);
			boolean alphaPremultiplied = cm.isAlphaPremultiplied();
			target = new BufferedImage(cm, raster, alphaPremultiplied, null);
		} else
			target = new BufferedImage(targetW, targetH, type);
		Graphics2D g = target.createGraphics();
		// smoother than exlax:
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
		g.dispose();
		return target;
	}

	/**
	 * 根据指定的长宽比例进行裁图
	 * 
	 * @param pic
	 *            原图字节码
	 * @param ratio
	 *            图片裁剪比例
	 * @return
	 * @throws IOException
	 */
	private static BufferedImage cropImage(byte[] pic, double ratio)
			throws IOException {
		BufferedImage srcImage = ImageIO.read(new ByteArrayInputStream(pic));
		int sourceWidth = srcImage.getWidth();
		int sourceHeight = srcImage.getHeight();
		double origRatio = (double) sourceWidth / sourceHeight;
		int newWidth, newHeight;
		if (origRatio < ratio) {
			newHeight = (int) (sourceWidth / ratio);
			newWidth = (int) (newHeight * ratio);
		} else {
			newWidth = (int) (sourceHeight * ratio);
			newHeight = (int) (newWidth / ratio);
		}
		BufferedImage cutImage = srcImage.getSubimage(
				(sourceWidth - newWidth) / 2, (sourceHeight - newHeight) / 2,
				newWidth, newHeight);// 裁图
		return cutImage;
	}

	public static void saveImageAsJpg(String fromFileStr, String saveToFileStr,
			int width, int hight) throws Exception {
		BufferedImage srcImage;
		// String ex =
		// fromFileStr.substring(fromFileStr.indexOf("."),fromFileStr.length());
		String imgType = "JPEG";
		if (fromFileStr.toLowerCase().endsWith(".png")) {
			imgType = "PNG";
		}
		// System.out.println(ex);
		File saveFile = new File(saveToFileStr);
		File fromFile = new File(fromFileStr);
		srcImage = ImageIO.read(fromFile);
		if (width > 0 || hight > 0) {
			srcImage = thumbnail(srcImage, width, hight);
		}
		ImageIO.write(srcImage, imgType, saveFile);

	}

	public static void main(String argv[]) {
		try {
			// 参数1(from),参数2(to),参数3(宽),参数4(高)
			/*
			 * ThumbnailGeneral .saveImageAsJpg(
			 * "C:\\Users\\wb-zhengjunwei\\Pictures\\QQ浏览器截图\\alipay.bmp",
			 * "C:\\Users\\wb-zhengjunwei\\Pictures\\QQ浏览器截图\\alipay_min.bmp",
			 * 150, 150);
			 */
			FileInputStream f = new FileInputStream(
					"C:\\Users\\wb-zhengjunwei\\Pictures\\QQ浏览器截图\\alipay.bmp");
			byte[] b = new byte[f.available()];
			f.read(b);
			f.close();
			FileOutputStream out = new FileOutputStream(
					"C:\\Users\\wb-zhengjunwei\\Pictures\\QQ浏览器截图\\alipay_min.bmp");
			out.write(generateThumbnail(b, 40, 6));
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
